From 3fa06e049012218d883d0e1251df86bafbc446bf Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Thu, 22 Nov 2018 11:03:35 +0100
Subject: [PATCH] setarch: fix obscure sparc32bash use-case

Reported-by: Carlos Santos <casantos@datacom.com.br>
Signed-off-by: Karel Zak <kzak@redhat.com>
Signed-off-by: Carlos Santos <casantos@datacom.com.br>
---
 sys-utils/setarch.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/sys-utils/setarch.c b/sys-utils/setarch.c
index a733f7b3c..7c0a63fbb 100644
--- a/sys-utils/setarch.c
+++ b/sys-utils/setarch.c
@@ -268,6 +268,7 @@ int main(int argc, char *argv[])
 	int c;
 	struct arch_domain *doms, *target;
 	unsigned long pers_value = 0;
+	char *shell = NULL, *shell_arg = NULL;
 
 	/* Options without equivalent short options */
 	enum {
@@ -310,14 +311,14 @@ int main(int argc, char *argv[])
 	archwrapper = strcmp(program_invocation_short_name, "setarch") != 0;
 	if (archwrapper) {
 		arch = program_invocation_short_name;	/* symlinks to setarch */
-#if defined(__sparc64__) || defined(__sparc__)
+
+		/* Don't use ifdef sparc here, we get "Unrecognized architecture"
+		 * error message later if necessary */
 		if (strcmp(arch, "sparc32bash") == 0) {
-			if (set_arch(arch, 0L, 0))
-				err(EXIT_FAILURE, _("Failed to set personality to %s"), arch);
-			execl("/bin/bash", "", NULL);
-			errexec("/bin/bash");
+			shell = "/bin/bash";
+			shell_arg = "";
+			goto set_arch;
 		}
-#endif
 	} else {
 		if (1 < argc && *argv[1] != '-') {
 			arch = argv[1];
@@ -391,6 +392,7 @@ int main(int argc, char *argv[])
 	argc -= optind;
 	argv += optind;
 
+set_arch:
 	/* get execution domain (architecture) */
 	if (arch) {
 		doms = init_arch_domains();
@@ -422,17 +424,23 @@ int main(int argc, char *argv[])
 	if (arch)
 		verify_arch_domain(target, arch);
 
+	if (!argc) {
+		shell = "/bin/sh";
+		shell_arg = "-sh";
+	}
 	if (verbose) {
-		printf(_("Execute command `%s'.\n"), argc ? argv[0] : "/bin/sh");
+		printf(_("Execute command `%s'.\n"), shell ? shell : argv[0]);
 		/* flush all output streams before exec */
 		fflush(NULL);
 	}
 
-	if (!argc) {
-		execl("/bin/sh", "-sh", NULL);
-		errexec("/bin/sh");
+	/* Execute shell */
+	if (shell) {
+		execl(shell, shell_arg, NULL);
+		errexec(shell);
 	}
 
+	/* Execute on command line specified command */
 	execvp(argv[0], argv);
 	errexec(argv[0]);
 }
-- 
2.14.5

